home *** CD-ROM | disk | FTP | other *** search
/ Programmers Heaven 2 / Programmers Heaven 2.iso / files / graphics / library / wgt51_r2.zip / WGT5 / EXAMPLES / WGT68 / WGT68E.C < prev   
Encoding:
C/C++ Source or Header  |  1996-08-03  |  9.7 KB  |  445 lines

  1. #include <wgt5.h>
  2. #include <math.h>
  3.  
  4. /*
  5. ==============================================================================
  6.               WordUp Graphics Toolkit Version 5.0
  7.                  Demonstration Program 68e
  8.  
  9.  Same as wgt68d.c, but shows the shaded resize routine.
  10.  This one requires a mouse.  Hit a key to cycle through each of the
  11.  resize shading modes.  ESC or Q quits the program.
  12.  
  13.  *** PROJECT ***
  14.  This program requires the WGT5_WC.LIB file to be linked.
  15.  
  16.  *** DATA FILES ***
  17.  STREET.PAL, RUN.SPR
  18.                                WATCOM C++ VERSION
  19. ==============================================================================
  20. */
  21.  
  22. unsigned char shadowtable[256];    /* Shadow table */
  23. unsigned char *transparency_table; /* a 65536 byte table,
  24.                       allocated dynamically */
  25.  
  26. color pal[256];         /* The palette used for every graphic image */
  27. block sprites[200];     /* Array of images for the running robot */
  28.  
  29. block background;       /* Holds the background scrolling image */
  30. block work;             /* Page for constructing each frame */
  31. int oldmode;
  32.  
  33. int animation_count;    /* Used for animation timing */
  34. int movement_multiplier;/* Number of times to move objects, ground, etc */
  35. int resize_mode;        /* Shade technique used for resize */
  36.  
  37. /* A structure which holds the scrolling values for each horizontal line */
  38. typedef struct
  39.  {
  40.   int x;                /* Current x value, shifted by 8 */
  41.   int increment;        /* fixed point increment */
  42.  } line_scroll;
  43. line_scroll lines[80];  /* 80 scrolling lines along the ground */
  44.  
  45. /* A simple sprite structure */
  46. typedef struct
  47.  {
  48.   int x;
  49.   int y;
  50.   int anm;              /* Sprite number */
  51.  } sprite;
  52. sprite people[5];
  53.  
  54.  
  55. int backx = 0;          /* X value for the scrolling rocks */
  56. int backinc;            /* X increment for scrolling rocks */
  57.  
  58.  
  59. /* Loads the graphics files, and allocates buffers */
  60. void load_graphics (void)
  61. {
  62.  work = wallocblock (320, 200);
  63.  /* Allocate a work buffer */
  64.  
  65.  wloadsprites (pal, "run.spr", sprites, 0, 199);
  66.  background = wloadpak ("street.pak");
  67.  wsetpalette (0, 255, pal);
  68.  
  69.  transparency_table = (unsigned char *)malloc (65536);
  70. }
  71.  
  72.  
  73.  
  74. /* Frees the buffers and sprites */
  75. void free_graphics (void)
  76. {
  77.  free (transparency_table);
  78.  wfreesprites (sprites, 0, 199);
  79.  wfreeblock (background);
  80.  wfreeblock (work);
  81. }
  82.  
  83.  
  84. /* Set up the initial scrolling values */
  85. void init_lines (void)
  86. {
  87. int i;
  88. int inc;
  89.  
  90.  inc = 128;     /* slowest scrolling speed (128/256 of a pixel */
  91.  
  92.  backx = 0;     /* rocks x value */
  93.  backinc = inc; /* rocks same speed as the ground */
  94.  
  95.  for (i = 0; i < 80; i++)
  96.   {
  97.    lines[i].x = 0;              /* clear out the x value */
  98.    lines[i].increment = inc;    /* set the scroll speed */
  99.    inc += 32;                   /* Make the next row move faster */
  100.   }
  101.  
  102. }
  103.  
  104.  
  105.  
  106. /* Construct the background image */
  107. void animate_lines (void)
  108. {
  109. block source1, source2;
  110. block dest1, dest2;
  111. block origsource, origdest;
  112. int i;
  113. int x;
  114. int mult;
  115.  
  116.  wcopyscreen (0, 0, 319, 51, background, 0, 0, work);
  117.  /* Draw the moon stationary */
  118.  
  119.  /* Scroll the rocks */
  120.  for (mult = 0; mult <= movement_multiplier; mult++)
  121.    {
  122.     backx += backinc;
  123.     if (backx >= 81920)   /* 81920 is 320 << 8 */
  124.        backx -= 81920;
  125.    }
  126.  
  127.  x = backx >> 8;
  128.  
  129.  /* Copy the rocks */
  130.  wcopyscreen (x, 52, 319, 119, background, 0, 52, work);
  131.  if (x > 0)
  132.    wcopyscreen (0, 52, x-1, 119, background, 320 - x, 52, work);
  133.  
  134.  
  135.  origdest = abuf + 120 * 320;           /* First row to copy */
  136.  origsource = background + 120 * 320;   /* First row to copy */
  137.  
  138.  for (i = 0; i < 80; i++)
  139.   {
  140.    /* Scroll this line */
  141.    for (mult = 0; mult <= movement_multiplier; mult++)
  142.     {
  143.      lines[i].x += lines[i].increment;
  144.      if (lines[i].x >= 81920)   /* 81920 is 320 << 8, wraps scroll around */
  145.     lines[i].x -= 81920;
  146.     }
  147.    
  148.    x = lines[i].x >> 8;
  149.    /* Get the x coord */
  150.  
  151.    dest1 = origdest + i * 320;
  152.    dest2 = dest1 + (319 - x);
  153.    source1 = origsource + i * 320;
  154.    source2 = source1 + x;
  155.    
  156.    /* Copy the line in two steps */
  157.    memcpy (dest1, source2, 320 - x);
  158.    if (x > 0)
  159.     memcpy (dest2, source1, x + 1);
  160.    
  161.   }
  162.  
  163. }
  164.  
  165.  
  166.  
  167. /* Animates and displays the running man */
  168. void animate_man (void)
  169. {
  170. unsigned char monocolor;
  171. int mult;
  172. short rx, ry; 
  173.  
  174.  for (mult = 0; mult <= movement_multiplier; mult++)
  175.  {
  176.   people[0].anm++;
  177.   if (people[0].anm > 29)
  178.     people[0].anm = 0;
  179.  }
  180.  
  181.  rx = mouse.mx;
  182.  ry = mouse.my;
  183.  
  184.  switch (resize_mode)
  185.  {
  186.   case 0:  wresize_shade (0, 0, rx, ry, sprites[people[0].anm],
  187.        shadowtable, SHADE_NORMAL);
  188.        break;
  189.   case 1:  wresize_shade (0, 0, rx, ry, sprites[people[0].anm],
  190.        shadowtable, SHADE_XRAY);
  191.        break;
  192.   case 2:  wresize_shade (0, 0, rx, ry, sprites[people[0].anm],
  193.        shadowtable, SHADE_SHADOW);
  194.        break;
  195.   case 3:  wresize_shade (0, 0, rx, ry, sprites[people[0].anm],
  196.        transparency_table, SHADE_TRANSLUCENT);
  197.        break;
  198.   case 4:  monocolor = 15;
  199.        wresize_shade (0, 0, rx, ry, sprites[people[0].anm],
  200.        &monocolor, SHADE_MONO);
  201.        break;
  202.   }
  203.  
  204.  
  205.  wputblock_shade (people[0].x, 158, sprites[people[0].anm+30],
  206.         shadowtable, SHADE_SHADOW);
  207.  wputblock_shade (people[0].x, people[0].y, sprites[people[0].anm],
  208.         transparency_table, SHADE_TRANSLUCENT);
  209. }
  210.  
  211.  
  212.  
  213. void wcreate_shadow_table (color *palette)
  214. {
  215. float fr, fg, fb;
  216. long ir, ig, ib;
  217.  
  218. long absr, absg, absb;
  219.  
  220.  
  221. int r,g,b;
  222.  
  223. short col;
  224. short findcol;
  225.  
  226. unsigned long lowest;
  227. unsigned char bestfit;
  228. unsigned long coldif;
  229.  
  230.  for (col = 0; col < 256; col++)
  231.   {
  232.  
  233.    fr = (float)palette[col].r * (0.5);
  234.    fg = (float)palette[col].g * (0.5);
  235.    fb = (float)palette[col].b * (0.5);
  236.  
  237.    ir = fr;
  238.    ig = fg;
  239.    ib = fb;
  240.  
  241.    lowest = 655350;
  242.    for  (findcol = 0; findcol < 256; findcol++)
  243.     {
  244.       absr = abs ( (long)palette[findcol].r - ir);
  245.       absg = abs ( (long)palette[findcol].g - ig);
  246.       absb = abs ( (long)palette[findcol].b - ib);
  247.  
  248.       coldif = absr + absg + absb;
  249.       if  ((coldif < lowest) && (findcol != col))
  250.       {
  251.     lowest = coldif;
  252.     bestfit = findcol;
  253.       }
  254.     }
  255.    shadowtable[col] = bestfit;
  256.   }
  257.  
  258. }
  259.  
  260.  
  261. void wcreate_transparency_table (color *pal)
  262. {
  263. float lightlevel1;
  264. float lightlevel2;
  265. float fr, fg, fb;
  266. float fr2, fg2, fb2;
  267. long ir, ig, ib;
  268.  
  269. long absr, absg, absb;
  270.  
  271. short col, col2;
  272. short findcol;
  273.  
  274. unsigned long lowest;
  275. unsigned char bestfit;
  276. unsigned long coldif;
  277.  
  278.  
  279.  lightlevel1 = 0.5;     /* Percent of color 1 */
  280.  lightlevel2 = 0.5;     /* Percent of color 2 */
  281.  
  282.  /* Lightlevel1 and lightlevel2 must total to 1 */
  283.  
  284.  /* Transparency is created by taking two colors, multiplying the
  285.  RGB values by a percentage, and adding the RGB values together.  The
  286.  new color will contain a little bit of each oringal color. */
  287.  
  288.  
  289.  /* For each of the 256 colors, we can mix with any other color, therefore
  290.  we need a 256x256 table. */
  291.  
  292.  wtextcolor (15);
  293.  wtexttransparent (TEXTFGBG);
  294.  wgtprintf (0, 0, NULL, "Making transparency table...", col2);
  295.  
  296.  for (col2 = 0; col2 < 256; col2++)
  297.  {
  298.   for (col = 0; col < 256; col++)
  299.   {
  300.    fr = (float)pal[col].r * lightlevel1;
  301.    fg = (float)pal[col].g * lightlevel1;
  302.    fb = (float)pal[col].b * lightlevel1;
  303.  
  304.    fr2= (float)pal[col2].r * lightlevel2;
  305.    fg2= (float)pal[col2].g * lightlevel2;
  306.    fb2= (float)pal[col2].b * lightlevel2;
  307.  
  308.    ir = (fr + fr2);
  309.    ig = (fg + fg2);
  310.    ib = (fb + fb2);
  311.  
  312.    lowest = 655350;
  313.    for  (findcol = 0; findcol < 256; findcol++)
  314.     {
  315.       absr = abs ( (long)pal[findcol].r - ir) * 30;
  316.       absg = abs ( (long)pal[findcol].g - ig) * 59;
  317.       absb = abs ( (long)pal[findcol].b - ib) * 11;
  318.  
  319.       coldif = sqrt(absr*absr + absg*absg + absb*absb);
  320.       if  (coldif < lowest)
  321.       {
  322.     lowest = coldif;
  323.     bestfit = findcol;
  324.       }
  325.     }
  326.    transparency_table[col2 * 256L + col] = bestfit;
  327.   }
  328.  
  329.   wgtprintf (0, 8, NULL, "Color %03hi", col2);
  330.  }
  331.  
  332. }
  333.  
  334.  
  335. void animation_timer (void)
  336. {
  337.  animation_count++;
  338. }
  339.  
  340.  
  341.  
  342. int load_table (char *filename, block table, int size)
  343. {
  344. FILE *in;
  345.  
  346.  in = fopen (filename, "rb");
  347.  if (in == NULL)
  348.    return 0;
  349.  fread (table, size, 1, in);
  350.  fclose (in);
  351.  return 1;
  352. }
  353.  
  354.  
  355. void save_table (char *filename, block table, int size)
  356. {
  357. FILE *out;
  358.  
  359.  out = fopen (filename, "wb");
  360.  fwrite (table, size, 1, out);
  361.  fclose (out);
  362.  
  363. }
  364.  
  365.  
  366.  
  367. void main (void)
  368. {
  369. char c;
  370.  
  371.   oldmode = wgetmode ();
  372.   if (!vgadetected ())
  373.   {
  374.     printf ("VGA is required to run this program...");
  375.     exit (1);
  376.   }
  377.  
  378.   printf ("WGT Example #68e\n\n");
  379.   printf ("Adds the shaded resize routine to perform special lighting effects.\n");
  380.   printf ("This one requires a mouse.  Hit a key to cycle through each of the\n");
  381.   printf ("resize shading modes.  ESC or Q quits the program.\n");
  382.   printf ("\nPress any key to begin.\n");
  383.   getch ();
  384.  
  385.  vga256 ();
  386.  
  387.  load_graphics ();
  388.  
  389.  init_lines ();
  390.  
  391.  minit ();
  392.  
  393.  /* Set the position of the running man */
  394.  people[0].x = 120;
  395.  people[0].y = 50;
  396.  people[0].anm = 0;
  397.  
  398.  wcreate_shadow_table (pal);
  399.  
  400.  if (!load_table ("trans.dat", transparency_table, 65536))
  401.   { 
  402.    wcreate_transparency_table (pal);
  403.    save_table ("trans.dat", transparency_table, 65536); 
  404.   }
  405.  
  406.  
  407.  animation_count = 0;
  408.  winittimer ();
  409.  wstarttimer (animation_timer, TICKS (20));
  410.  
  411.  resize_mode = 0;
  412.  
  413.  do {
  414.   wsetscreen (work);
  415.  
  416.   movement_multiplier = animation_count;
  417.   if (movement_multiplier > 0)
  418.    {
  419.     animation_count = 0;
  420.     
  421.     animate_lines ();
  422.     animate_man ();
  423.     wnormscreen ();
  424.  
  425.     wputblock (0, 0, work, 0);
  426.    }
  427.    if (kbhit ())
  428.     {
  429.      c = getch();
  430.      resize_mode++;
  431.      if (resize_mode > 4)
  432.      resize_mode = 0;
  433.     }
  434.  
  435.   } while ((c != 27) && (c != 'q') && (c != 'Q'));
  436.  
  437.  wstoptimer ();
  438.  wdonetimer ();
  439.  
  440.  free_graphics ();
  441.  mdeinit ();
  442.  wsetmode (oldmode);
  443. }
  444.  
  445.